// cabinet.js
const app = getApp()
const config = require('../../utils/config.js')
const NetworkUtils = require('../../utils/network.js')
const MqttListener = require('../../utils/mqttListener.js')

Page({
  data: {
    cabinets: [],
    totalCabinets: 0,
    availableCabinets: 0,
    usedCabinets: 0,
    loading: false,
    showModal: false,
    selectedCabinet: null,
    opening: false,
    retryCount: 0,
    serverConnected: false,
    // 开柜进度相关
    showOpenProgress: false,
    progressStep: 0,
    progressTitle: '',
    progressDesc: ''
  },

  onLoad() {
    this.registerMiniprogram()
    this.checkNetworkAndLoad()
  },
  
  // 注册小程序到服务器（让服务器知道小程序已连接）
  registerMiniprogram() {
    wx.request({
      url: `${config.serverUrl}/api/mqtt/message/publish`,
      method: 'POST',
      header: {
        'content-type': 'application/json'
      },
      data: {
        topic: config.mqttTopics.register,
        message: {
          type: 'MINIPROGRAM_CONNECT',
          clientId: 'miniprogram_client',
          timestamp: new Date().toISOString(),
          userAgent: 'WeChat MiniProgram',
          version: '1.0.0'
        }
      },
      success: (res) => {
        console.log('小程序注册成功:', res.data)
      },
      fail: (err) => {
        console.error('小程序注册失败:', err)
      }
    })
  },
  
  // 检查网络连接并加载数据
  async checkNetworkAndLoad() {
    try {
      console.log('开始网络诊断...')
      const diagnosis = await NetworkUtils.diagnoseNetwork()
      console.log('网络诊断结果:', diagnosis)
      
      if (diagnosis.serverReachable) {
        this.setData({ serverConnected: true })
        this.loadCabinets()
      } else {
        this.setData({ serverConnected: false })
        wx.showModal({
          title: '网络连接失败',
          content: '无法连接到服务器，请检查：\n1. 服务器是否启动 (端口3000)\n2. 网络连接是否正常\n3. 防火墙设置',
          showCancel: false,
          confirmText: '重试',
          success: () => {
            this.checkNetworkAndLoad()
          }
        })
      }
    } catch (err) {
      console.error('网络诊断失败:', err)
      this.setData({ serverConnected: false })
      this.loadCabinets() // 仍然尝试加载
    }
  },

  onShow() {
    // 页面显示时刷新数据
    this.loadCabinets()
  },

  // 加载柜子数据
  loadCabinets() {
    this.setData({ loading: true })
    
    console.log('正在请求服务器数据:', `${config.serverUrl}/api/boxes`)
    console.log('请求超时设置:', config.requestTimeout)
    
    wx.request({
      url: `${config.serverUrl}/api/boxes`,
      method: 'GET',
      timeout: config.requestTimeout,
      enableHttp2: false,
      enableQuic: false,
      success: (res) => {
        console.log('获取柜子数据成功:', res)
        console.log('响应状态码:', res.statusCode)
        console.log('响应数据:', res.data)
        console.log('响应头:', res.header)
        
        if (res.statusCode === 200) {
          this.setData({ 
            serverConnected: true,
            retryCount: 0 
          })
          // 只取前12个柜子
          const cabinets = res.data.slice(0, 12)
          
          // 计算统计数据
          const totalCabinets = cabinets.length
          const availableCabinets = cabinets.filter(c => c.status === config.cabinetStatus.AVAILABLE).length
          const usedCabinets = cabinets.filter(c => c.status === config.cabinetStatus.OCCUPIED).length
          
          this.setData({
            cabinets: cabinets,
            totalCabinets: totalCabinets,
            availableCabinets: availableCabinets,
            usedCabinets: usedCabinets,
            loading: false
          })
        } else {
          this.showError('获取柜子数据失败')
        }
      },
      fail: (err) => {
        console.error('网络请求失败:', err)
        console.error('请求URL:', `${config.serverUrl}/api/boxes`)
        
        // 尝试重连
        if (!this.data.retryCount || this.data.retryCount < 3) {
          const retryCount = (this.data.retryCount || 0) + 1
          this.setData({ retryCount })
          
          wx.showToast({
            title: `连接失败，正在重试 ${retryCount}/3`,
            icon: 'none',
            duration: 2000
          })
          
          setTimeout(() => {
            this.loadCabinets()
          }, 2000)
        } else {
          this.setData({ retryCount: 0 })
          this.showError('网络连接失败，请检查：\n1. 服务器是否启动\n2. 网络连接是否正常\n3. 服务器地址是否正确')
        }
      }
    })
  },

  // 刷新柜子数据
  refreshCabinets() {
    wx.showToast({
      title: '刷新中...',
      icon: 'loading',
      duration: 1000
    })
    this.setData({ retryCount: 0 })
    this.loadCabinets()
  },
  
  // 网络诊断
  async diagnoseNetwork() {
    wx.showLoading({
      title: '诊断中...'
    })
    
    try {
      const diagnosis = await NetworkUtils.diagnoseNetwork()
      wx.hideLoading()
      
      let message = '网络诊断结果：\n'
      message += `服务器连接: ${diagnosis.serverReachable ? '✓ 正常' : '✗ 失败'}\n`
      message += `API接口: ${diagnosis.apiWorking ? '✓ 正常' : '✗ 失败'}\n`
      message += `MQTT功能: ${diagnosis.mqttWorking ? '✓ 正常' : '✗ 失败'}\n`
      
      if (diagnosis.errors.length > 0) {
        message += '\n错误信息：\n'
        message += diagnosis.errors.join('\n')
      }
      
      if (diagnosis.serverReachable && diagnosis.apiWorking && diagnosis.mqttWorking) {
        message += '\n✅ 系统运行正常！'
        this.setData({ serverConnected: true })
      } else {
        message += '\n⚠️ 发现问题，请检查服务器状态'
        this.setData({ serverConnected: false })
      }
      
      wx.showModal({
        title: '网络诊断',
        content: message,
        showCancel: false,
        confirmText: '确定'
      })
      
    } catch (err) {
      wx.hideLoading()
      wx.showModal({
        title: '诊断失败',
        content: `诊断过程出错：${err.message}`,
        showCancel: false
      })
    }
  },

  // 点击柜子
  onCabinetTap(e) {
    const cabinet = e.currentTarget.dataset.cabinet
    console.log('点击柜子:', cabinet)
    
    this.setData({
      selectedCabinet: cabinet,
      showModal: true
    })
  },

  // 隐藏弹窗
  hideModal() {
    this.setData({
      showModal: false,
      selectedCabinet: null,
      opening: false
    })
  },

  // 开柜操作
  openCabinet() {
    const cabinet = this.data.selectedCabinet
    if (!cabinet) return

    this.setData({ opening: true })

    // 根据柜子状态显示不同的确认信息
    const isTestMode = cabinet.status === 0
    const isOpening = cabinet.status === 2
    
    let title, content
    
    if (isOpening) {
      // 开启中状态 - 重试开门
      title = '重新发送开门指令'
      content = `柜子 ${cabinet.boxId} 正在开启中，是否重新发送开门指令？\n这可能有助于解决开门问题。`
    } else if (isTestMode) {
      // 空闲状态 - 测试开门
      title = '确认测试开柜'
      content = `确定要测试开启柜子 ${cabinet.boxId} 吗？\n这将发送开门指令到快递柜设备。`
    } else {
      // 占用状态 - 正常开门取件
      title = '确认开柜取件'
      content = `确定要开启柜子 ${cabinet.boxId} 进行取件吗？`
    }

    wx.showModal({
      title: title,
      content: content,
      success: (res) => {
        if (res.confirm) {
          this.performOpenCabinet(cabinet, isTestMode)
        } else {
          this.setData({ opening: false })
        }
      }
    })
  },

  // 执行开柜操作
  performOpenCabinet(cabinet, isTestMode = false) {
    const isRetry = cabinet.status === 2
    console.log('开柜操作:', cabinet, '测试模式:', isTestMode, '重试操作:', isRetry)
    
    // 构建开柜指令，符合设备端期望的ControlMessage接口
    const openCommand = {
      command: {
        action: 'OPEN_DOOR',     // 开门动作
        boxId: cabinet.boxId,    // 柜子ID
        lockNumber: cabinet.lockNumber, // 锁编号
        doorId: cabinet.id      // 门ID
      },
      timestamp: new Date().toISOString(),
      target_device: 'HarmonyOS设备1', // 目标设备
      testMode: isTestMode     // 标识是否为测试模式
    }
    
    console.log('发送开柜指令到服务器:', openCommand)
    console.log('MQTT主题:', config.mqttTopics.control)
    console.log('服务器URL:', config.serverUrl)

    // 先测试直接HTTP请求
    console.log('开始发送HTTP请求...')
    wx.request({
      url: `${config.serverUrl}/api/mqtt/message/publish`,
      method: 'POST',
      header: {
        'content-type': 'application/json'
      },
      data: {
        topic: config.mqttTopics.commands,
        message: openCommand
      },
      success: (res) => {
        console.log('HTTP请求成功:', res)
        if (res.statusCode === 200) {
          console.log('开柜指令发送成功，开始更新状态...')
          
          // 更新柜子状态为开启中
          wx.request({
            url: `${config.serverUrl}/api/boxes/${cabinet.id}/status`,
            method: 'POST',
            header: {
              'content-type': 'application/json'
            },
            data: {
              status: config.cabinetStatus.OPENING
            },
            success: (statusRes) => {
              console.log('状态更新成功:', statusRes)
              
              // 立即更新本地状态，不等待服务器响应
              this.updateLocalCabinetStatus(cabinet.id, config.cabinetStatus.OPENING)
              
              this.hideModal()
              
              // 显示开柜进度
              this.showOpeningProgress(cabinet, isTestMode)
              
              // 启动MQTT响应监听
              this.startMqttResponseListener(cabinet, isTestMode)
              
              // 备用：10秒后强制恢复状态
              setTimeout(() => {
                console.log('开柜操作超时，强制恢复柜子状态')
                this.hideOpeningProgress()
                this.updateLocalCabinetStatus(cabinet.id, isTestMode ? config.cabinetStatus.AVAILABLE : config.cabinetStatus.OCCUPIED)
                this.loadCabinets()
              }, 10000)
            },
            fail: (statusErr) => {
              console.error('状态更新失败:', statusErr)
              console.error('状态更新错误详情:', JSON.stringify(statusErr))
              
              // 即使状态更新失败，也要更新本地显示
              this.updateLocalCabinetStatus(cabinet.id, config.cabinetStatus.OPENING)
              
              wx.showToast({
                title: '开柜指令已发送（状态更新失败）',
                icon: 'none',
                duration: 3000
              })
              this.hideModal()
              
              // 5秒后刷新
              setTimeout(() => {
                this.loadCabinets()
              }, 5000)
            }
          })
        } else {
          console.error('HTTP请求返回错误状态:', res.statusCode, res.data)
          this.showError(`发送失败: HTTP ${res.statusCode}`)
        }
      },
      fail: (err) => {
        console.error('HTTP请求失败:', err)
        this.showError(`网络请求失败: ${err.errMsg || err.message || '未知错误'}`)
      },
      complete: () => {
        this.setData({ opening: false })
      }
    })

    // 注释掉原来的NetworkUtils调用，先用直接HTTP请求调试
    /*
    // 使用网络工具发送MQTT指令
    NetworkUtils.sendMqttCommand(config.mqttTopics.control, openCommand)
    */
  },

  // 更新本地柜子状态（立即生效）
  updateLocalCabinetStatus(cabinetId, newStatus) {
    console.log(`更新本地柜子状态: ID=${cabinetId}, 新状态=${newStatus}`)
    
    const cabinets = this.data.cabinets.map(cabinet => {
      if (cabinet.id === cabinetId) {
        return { ...cabinet, status: newStatus }
      }
      return cabinet
    })
    
    // 重新计算统计数据
    const totalCabinets = cabinets.length
    const availableCabinets = cabinets.filter(c => c.status === config.cabinetStatus.AVAILABLE).length
    const usedCabinets = cabinets.filter(c => c.status === config.cabinetStatus.OCCUPIED).length
    
    this.setData({
      cabinets: cabinets,
      totalCabinets: totalCabinets,
      availableCabinets: availableCabinets,
      usedCabinets: usedCabinets
    })
  },

  // 更新柜子状态
  updateCabinetStatus(cabinetId, status) {
    wx.request({
      url: `${config.serverUrl}/api/boxes/${cabinetId}/status`,
      method: 'POST',
      header: {
        'content-type': 'application/json'
      },
      data: {
        status: status
      },
      success: (res) => {
        console.log('更新柜子状态成功:', res.data)
        // 刷新本地数据
        this.loadCabinets()
      },
      fail: (err) => {
        console.error('更新柜子状态失败:', err)
      }
    })
  },

  // 分配柜子
  assignCabinet() {
    const cabinet = this.data.selectedCabinet
    if (!cabinet) return

    wx.showModal({
      title: '分配柜子',
      content: `将柜子 ${cabinet.boxId} 分配给用户`,
      editable: true,
      placeholderText: '请输入手机号',
      success: (res) => {
        if (res.confirm && res.content) {
          const phone = res.content.trim()
          if (this.validatePhone(phone)) {
            this.performAssignCabinet(cabinet, phone)
          } else {
            wx.showToast({
              title: '请输入正确的手机号',
              icon: 'none'
            })
          }
        }
      }
    })
  },

  // 执行分配柜子
  performAssignCabinet(cabinet, phone) {
    // 这里可以调用服务器API来分配柜子
    wx.showToast({
      title: '分配成功',
      icon: 'success'
    })
    
    this.hideModal()
    this.loadCabinets()
  },

  // 验证手机号
  validatePhone(phone) {
    const phoneRegex = /^1[3-9]\d{9}$/
    return phoneRegex.test(phone)
  },

  // 显示开柜进度
  showOpeningProgress(cabinet, isTestMode) {
    const title = isTestMode ? '测试开柜中' : '正在开柜'
    const desc = `柜子 ${cabinet.boxId} 正在执行开门操作...`
    
    this.setData({
      showOpenProgress: true,
      progressStep: 1,
      progressTitle: title,
      progressDesc: desc
    })
    
    // 模拟进度步骤
    setTimeout(() => {
      this.setData({ progressStep: 2, progressDesc: '设备正在处理开门指令...' })
    }, 1000)
    
    setTimeout(() => {
      this.setData({ progressStep: 3, progressDesc: '柜门即将打开...' })
    }, 2500)
  },
  
  // 隐藏开柜进度
  hideOpeningProgress() {
    this.setData({
      showOpenProgress: false,
      progressStep: 0,
      progressTitle: '',
      progressDesc: ''
    })
  },

  // 启动MQTT响应监听
  startMqttResponseListener(cabinet, isTestMode) {
    console.log('启动MQTT响应监听，柜子ID:', cabinet.id)
    
    // 移除模拟响应，等待真实的MQTT响应
    
    // 方法2：通过WebSocket监听设备响应
    try {
      MqttListener.connectWebSocket((data) => {
        console.log('WebSocket收到消息:', data)
        if (data.type === 'message_received' && data.topic === 'kaihong/devices/response') {
          try {
            const responseData = JSON.parse(data.payload)
            if (responseData.type === 'CONTROL_RESPONSE' && responseData.command && 
                responseData.command.boxId === cabinet.boxId) {
              console.log('收到开柜响应:', responseData)
              this.handleDeviceResponse(cabinet, responseData, isTestMode)
            }
          } catch (e) {
            console.error('解析设备响应失败:', e)
          }
        }
      })
    } catch (error) {
      console.log('WebSocket不可用:', error)
    }
    
    // 方法3：轮询检查柜子状态变化
    let pollCount = 0
    const pollInterval = setInterval(() => {
      pollCount++
      if (pollCount > 10) { // 最多轮询10次（30秒）
        clearInterval(pollInterval)
        return
      }
      
      // 检查柜子状态是否有变化
      wx.request({
        url: `${config.serverUrl}/api/boxes`,
        method: 'GET',
        success: (res) => {
          if (res.statusCode === 200) {
            const updatedCabinet = res.data.find(c => c.id === cabinet.id)
            if (updatedCabinet && updatedCabinet.status !== config.cabinetStatus.OPENING) {
              console.log('检测到柜子状态变化:', updatedCabinet)
              clearInterval(pollInterval)
              this.hideOpeningProgress()
              this.loadCabinets()
            }
          }
        }
      })
    }, 3000) // 每3秒轮询一次
  },
  
  // 处理设备响应
  handleDeviceResponse(cabinet, response, isTestMode) {
    console.log('处理设备响应:', response)
    
    if (response.status === 'SUCCESS' || response.status === 'OPENED') {
      // 隐藏进度显示
      this.hideOpeningProgress()
      
      wx.showToast({
        title: '✅ 柜门已成功打开！',
        icon: 'success',
        duration: 2000
      })
      
      // 2秒后恢复状态
      setTimeout(() => {
        this.updateLocalCabinetStatus(cabinet.id, isTestMode ? config.cabinetStatus.AVAILABLE : config.cabinetStatus.OCCUPIED)
      }, 2000)
      
    } else if (response.status === 'FAILED') {
      // 隐藏进度显示
      this.hideOpeningProgress()
      
      wx.showToast({
        title: '❌ 开柜失败：' + (response.message || '未知错误'),
        icon: 'none',
        duration: 3000
      })
      
      // 立即恢复状态
      this.updateLocalCabinetStatus(cabinet.id, isTestMode ? config.cabinetStatus.AVAILABLE : config.cabinetStatus.OCCUPIED)
    }
  },

  // 显示错误信息
  showError(message) {
    this.setData({ loading: false, opening: false })
    wx.showToast({
      title: message,
      icon: 'none',
      duration: 3000
    })
  }
})